package cn.itcast.demo3;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import org.junit.Test;

import cn.itcast.demo2.SupPerson;

public class Demo2 
{
	@Test
	public void test1()
	{
		// 要被增强的对象
		final NormalPerson p=new NormalPerson();
		
		// 需求: 使用动态代理的方式对普通人进行增强
		// jdk提供的类和方法可以给咱们动态的生成代理对象/增强对象 不需要自己去创建增强类
		
		/*参数概述: 固定死的
		 *  参数1: 和要被增强的对象一样的类加载器
		 *  参数2: 和要被增强的对象一样的接口
		 *  					1 根据指定的传递接口 返回一个该接口下的实例
		 *  					2 传递的接口 里面的方法就是可以被增强的所有方法
		 *  
		 *  参数3: 所有的增强业务逻辑实现 (方法)
		 * */
		Person proxyPerson =(Person)Proxy.newProxyInstance(
				p.getClass().getClassLoader(), 
				p.getClass().getInterfaces(),
				new InvocationHandler() {
					
					/*参数概述 固定死的
					 * 参数1:不用管 永远是固定值    代理对象的类型 
					 * 参数2: 要被增强的方法
					 * 参数3: 要被增强的方法运行过程中需要的参数
					 * */
					
					@Override //invoke里面是所有的增强业务逻辑代码
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						
						// 让以前的方法执行
							// 参数1:本身应该执行这个方法的对象
							// 参数2: 执行这个方法需要的参数
						Object value = method.invoke(p, args);
						// 原来方法的返回值
						System.out.println(value);
						// 写增强业务逻辑
						System.out.println("增强了:变成飞...");
						
						// 最终返回值 谁调用返回给谁
						return method.invoke(p, args);
					}
				});
		
		//SupPerson sup=new SupPerson(p);
		//sup.run();
		//proxyPerson.run(); // 执行这个方法  invoke都会执行一遍   执行的内容就是针对该方法的增强
		
		//proxyPerson.run1(); // 执行这个方法  invoke都会执行一遍   执行的内容就是针对该方法的增强
		
		String value = proxyPerson.sleep();
		System.out.println(value);
	}
}
